#include <semaphore.h>
#include <stdio.h>
#include <pthread.h>

#define M 8
#define N 10

sem_t space, prod, sin, sout,buf;

int Buffer[N];  
int in=0, out =0; 


void Swait(sem_t S_1, sem_t S_2)
{
    /*
    sem_trywait ( sem_t *sem )是函数sem_wait（）的非阻塞版本
    它直接将信号量sem的值减一。在成功完成之后会返回零。其他任何返回值都表示出现了错误。
    */
    while(sem_trywait(&S_1) || sem_trywait(&S_2)); //两个都为0时退出while循环
}

void Ssignal(sem_t S_1, sem_t S_2){
    sem_post(&S_1);
    sem_post(&S_2);
}

void * producer(void *p){
    while(1){
        Swait(space, buf);
        printf("Put a product into Buffer[%d]!\n", in);
        in = (in +1)%N; 
        Ssignal(prod, buf);
    } 
    return NULL;
}

void * consumer(void *p){
    while(1){
        Swait(prod, buf);
        printf ("Get a product from Buffer[%d]!\n", out);
        out = (out +1)%N; 
        Ssignal(space, buf);
     }  
     return NULL;
}


int main(void)
{
    sem_init(&space, 0, N); 
    sem_init(&prod, 0, 0);
    sem_init(&sin, 0, 1);       
    sem_init(&sout, 0, 1);
    sem_init(&buf, 0, 1);
    pthread_t tid[M], tid2[M];
    for(int i=0; i<M; i++) 
        pthread_create(&tid[i], NULL, producer, NULL);
    for(int i=0; i<M; i++) 
        pthread_create(&tid2[i], NULL, consumer, NULL);
    sem_destroy(&space); 
    pthread_join(tid[M-1], NULL);
}